# -*- coding: utf-8 -*-
# Purpose: Node frame : view and edit a node
# Created: 12/03/2008
# Copyright (c) 2008,2009 by University College London
# Authors:
# Didrik Pinte <dpinte@dipole-consulting.com>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with HydroPlatform for details.

from sqlalchemy import or_
import logging
import wx

from hydroplatform.model.layer import NetworkLayer
from hydroplatform.model.network import Link, Node
from hydroplatform.model import networkfun
from hydroplatform.ui.objecteditordialog import ObjectEditorDialog
from hydroplatform.ui.tools import delete_network_object


class ObjectPopupMenu(wx.Menu):
    '''
    Object popup menu displayed when right clicking on it
    '''
    def __init__(self, context):
        wx.Menu.__init__(self)    
        self.context = context
        menu_titles = [ ("Edit", self.edit_object),
                    ("Delete", self.delete_object) ]
    
        self.menu_title_by_id = {}
        self.title_item = wx.MenuItem(self, wx.NewId(), 'Menu title')
        self.AppendItem(self.title_item)
        self.title_item.Enable(False)
        self.AppendSeparator()
        for (title, action) in menu_titles:
            item = wx.MenuItem(self, wx.NewId(), title)
            self.AppendItem(item)
            self.Bind(wx.EVT_MENU, action, item)
            
        self.selected_object = None
            
            
    def getlayer_bbox(self, cmap, bbox , layer):
        '''
        Transform a bbox from pixel coordinate system to layer coordinate 
        system.
        
        TODO : should be merged with the tools.ConvertCoordMixin
        '''
        if cmap.GetProjection() is not None:
            bbox = cmap.GetProjection().InverseBBox(bbox)
        if layer.projection is not None:
            bbox = layer.projection.ForwardBBox(bbox)
        return bbox

    def load_popup_menu(self, event):
        '''
        Load a popup menu under the mouse click.
        
        TODO : the common code with tools.IdentifyObject should be merged
        '''
        maxsize = 5
        canvas = self.context.mainwindow.canvas
        box = canvas.unprojected_rect_around_point(event.m_x, 
                                                   event.m_y, 
                                                   maxsize)
        cmap = canvas.map
        self.selected_object = None
        for layer in [layer for layer in cmap.Layers() \
                      if isinstance(layer, NetworkLayer)]:
            bbox = self.getlayer_bbox(cmap, box, layer)
            obj = layer.find_closest_node_in_box(bbox, unselect=True)
            if obj is not None:
                self.selected_object = obj
                obj.selected = True
                if isinstance(obj, Node):
                    self.title_item.SetText("Node %s" % obj.name)
                else:
                    name_refreshed= obj.start.name+'_'+obj.end.name
                    self.title_item.SetText("Link %s" % name_refreshed)
                    
                break
        else:
            pass
            
        self.context.mainwindow.canvas.PopupMenu( self, event.GetPosition() )

    def edit_object(self, event):
        '''
        Edit the selected object
        '''
        if self.selected_object is not None:
            frame = ObjectEditorDialog(self.context.mainwindow, 
                                       self.context, 
                                       self.selected_object)
            frame.ShowModal()
   
    def delete_object(self, event):
        '''
        Delete the selected object
        '''
        delete_network_object(self.context, self.context.session.hpnetwork, 
                              self.selected_object) 
        
